﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using GameBase;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
namespace GameBase.Form.Control
{

    
    public enum Align {Left, Right,Center };
    public abstract class MyControl : VisibleObject
    {
        public static Sprite TOOL_TIP_PANEL = new Sprite(@"System/pixel", 1, 1);
        public static Color[] COLOR_SET =
            new Color[] { Color.DeepPink, Color.Red, Color.OrangeRed,
                Color.Orange, Color.Yellow,Color.YellowGreen,
                Color.GreenYellow,Color.Cyan,Color.CornflowerBlue,
                Color.Aquamarine,Color.BlueViolet,Color.AliceBlue,
                Color.PaleVioletRed,Color.Chartreuse,Color.Bisque,
                Color.BlanchedAlmond,Color.Coral,Color.Fuchsia
            };
        //protected Sprite sprite;

        protected Align textAlign=Align.Center;
        protected int margin = 15;
        //bool showToolTipText = false;
        double hoverTime=0;
        
        string toolTipText;
        bool toolTipLeft = false;

        public bool ToolTipLeft
        {
            get { return toolTipLeft; }
            set { toolTipLeft = value; }
        }
        public string ToolTipText
        {
            get { return toolTipText; }
            set { toolTipText = value; }
        }
        public int Margin
        {
            get { return margin; }
            set { margin = value; }
        }
        protected bool isForcused = false;

        protected Color foreColor = Color.Black;
        protected bool isEnable = true;
        protected bool isHover = false;
        protected int defaultFrame = 0;
        protected int hoverFrame = 1;
        protected int pressedFrame = 2;
        protected Color disableColor = Color.LightGray;
        private Color enableColor = Color.White;

        protected Vector2 screenScale;
        protected String text;
        protected SpriteFont font = Constant.fontNormal;
        protected Rectangle bound;

        public delegate void CallBack(MyControl sender);
        public delegate void KeyCallBack(Keys releasedKey);

        private CallBack mousePressedCallBack = DefaultCallBack;
        private CallBack mouseReleasedCallBack = DefaultCallBack;
        private KeyCallBack keyPressedCallBack = DefaultKeyCallBack;
        private KeyCallBack keyReleasedCallBack = DefaultKeyCallBack;

        public Color DisableColor
        {
            get { return disableColor; }
            set { disableColor = value; }
        }

        public bool IsForcused
        {
            get { return isForcused; }
            set { isForcused = value; }
        }
        protected static void DefaultCallBack(MyControl sender)
        {
        }
        private static void DefaultKeyCallBack(Keys releasedKey)
        {
        }

        public Align TextAlign
        {
            get { return textAlign; }
            set { textAlign = value; }
        }
        public CallBack MousePressedCallBack
        {
            get { return mousePressedCallBack; }
            set { mousePressedCallBack = value; }
        }
        public CallBack MouseReleasedCallBack
        {
            get { return mouseReleasedCallBack; }
            set { mouseReleasedCallBack = value; }
        }
        public KeyCallBack KeyPressedCallBack
        {
            get { return keyPressedCallBack; }
            set { keyPressedCallBack = value; }
        }
        public KeyCallBack KeyReleasedCallBack
        {
            get { return keyReleasedCallBack; }
            set { keyReleasedCallBack = value; }
        }
        public SpriteFont Font
        {
            get { return font; }
            set { font = value; }
        }

        public String Text
        {
            get { return text; }
            set { text = value; }
        }
        
        public virtual Vector2 ScreenScale
        {
            get { return screenScale; }
            set
            {
                screenScale = value;
                UpdateBound();
            }
        }
        public override Vector2 Position
        {
            get
            {
                return position;
            }
            set
            {
                position = value;
                UpdateBound();
            }
        }
        public override Vector2 BasePosition
        {
            get
            {
                return basePosition;
            }
            set
            {
                basePosition = value;
                UpdateBound();
            }
        }
        protected virtual void UpdateBound()
        {
            if (Sprite == null)
            {
                return;
            }
            bound = Sprite.GetBound(
                new Vector2(position.X * screenScale.X, position.Y * screenScale.Y) +
                BasePosition,
                screenScale);
        }
        
        public int Width
        {
            get { return Sprite.Width; }
        }
        public int Height
        {
            get { return Sprite.Height; }
        }

        protected virtual bool IsHover(int x,int y)
        {
            
            return IsHover(x,y,bound);
        }

        public Color EnableColor
        {
            get { return enableColor; }
            set { enableColor = value; }
        }
        public bool IsEnable
        {
            get { return isEnable; }
            set
            {
                isEnable = value;
            }
        }
        public Color ForeColor
        {
            get { return foreColor; }
            set { foreColor = value; }
        }
        public override Color Color
        {
            get
            {
                return enableColor;
            }
            set
            {
                enableColor = value;
                
            }
        }
        public virtual void ControlUpdate(GameTime gameTime)
        {
            
            
        }
        public override void Update(GameTime gameTime)
        {
            bool showToolTipText = false;
            if (!Visible)
                return;

            if (Sprite != null)
            {
                if (isEnable)
                {
                    sprite.Color = enableColor;
                }
                else
                {
                    sprite.Color = DisableColor;
                }
            }
            //foreColor = Color.Lerp(Color, Color.Black, 0.8f);

            if (isEnable)
            {
            
                ControlUpdate(gameTime);
                MouseState mouseState = Mouse.GetState();
                isHover = IsHover(mouseState.X, mouseState.Y);
                if (isHover)
                {

                    if (depth < MyForm.MIN_DEPTH)
                    {
                        showToolTipText = true;

                        MyForm.MIN_DEPTH = depth;
                        if (mouseState.LeftButton == ButtonState.Pressed)
                        {
                            SetFrame(pressedFrame);
                        }
                        else
                        {
                            SetFrame(hoverFrame);
                        }
                        //return;
                    }
                    else
                    {
                        isHover = false;
                        SetFrame(defaultFrame);
                    }
                }
                else
                {
                    SetFrame(defaultFrame);
                }
            }
            else
            {
                SetFrame(pressedFrame);
                MouseState mouseState = Mouse.GetState();
                isHover = IsHover(mouseState.X, mouseState.Y);
                if (isHover)
                {
                    if (depth < MyForm.MIN_DEPTH)
                    {
                        showToolTipText = true;
                        MyForm.MIN_DEPTH = depth;
                    }
                    else
                    {
                        isHover = false;
                    }
                }
            }
            if (showToolTipText)
            {
                hoverTime += gameTime.ElapsedGameTime.TotalMilliseconds;

            }
            else
            {
                hoverTime = 0;
            }
        }
        public virtual void SetFrame(int frame)
        {
            if (Sprite != null)
            {
                Sprite.CurrentFrame = frame;
            }
        }
        public virtual MyControl ControlMouseInput(MouseState mouseState)
        {
            return this;
        }
        public virtual MyControl MouseInput(MouseState mouseState)
        {
            if (!IsEnable)
            {
                if (isHover)
                {
                    return this;
                }
                return null;
            }
            else if (!isHover || !isVisible)
            {
                return null;
            }
            if (mouseState.LeftButton == ButtonState.Pressed)
            {

                MousePressed(mouseState.X, mouseState.Y);
            }
            else
            {
                MouseReleased(mouseState.X, mouseState.Y);
            }
            isHover = false;
            return ControlMouseInput(mouseState);
        }
        public virtual void MousePressed(int x, int y)
        {
            MousePressedCallBack(this);
        }
        public virtual void MouseReleased(int x, int y)
        {
            MouseReleasedCallBack(this);
        }
        public virtual void KeyPressed(List<Keys> pressedKey)
        {
            foreach (Keys key in pressedKey)
            {
                keyPressedCallBack(key);
            }
        }
        public virtual void KeyRelease(List<Keys> releasedKey)
        {
            foreach (Keys key in releasedKey)
            {
                keyReleasedCallBack(key);
            }
        }
        protected Vector2 GetTextPosition()
        {
            Vector2 textSize = font.MeasureString(text);
            Vector2 spriteSize = new Vector2(bound.Width, bound.Height);
            int y = bound.Y + (int)((spriteSize.Y - textSize.Y) / 2);
            int x;
            int m = (int)(Margin * screenScale.X);
            switch (textAlign)
            {
                case Align.Left:
                    x = bound.X + m;
                    break;
                case Align.Right:
                    x = bound.X + bound.Width-(int)textSize.X- m;
                    break;
                default:
                    x = bound.X + (int)((spriteSize.X - textSize.X) / 2);
                    break;
            }

            return new Vector2(x, y);
           
        }
        public override void Draw(GameTime gameTime, SpriteBatch spriteBatch)
        {
            if (!Visible)
            {
                return;
            }
            
            if (Sprite != null)
            {
                Sprite.Draw(gameTime, spriteBatch,
                    new Vector2(bound.X, bound.Y), screenScale, depth);
            }
            if (text != null)
            {
                spriteBatch.DrawString(font, text, GetTextPosition(), foreColor,
                    0, Vector2.Zero, 1, SpriteEffects.None, depth-0.00001f);
            }
            if (hoverTime > 200 && toolTipText != null)
            {

                MouseState mouseState = Mouse.GetState();
                Vector2 textSize = font.MeasureString(toolTipText);
                //if()
                TOOL_TIP_PANEL.Color = Color.Lerp(sprite.Color,Color.Transparent,0.4f);
                Vector2 pos = new Vector2(mouseState.X, mouseState.Y - textSize.Y);
                if (ToolTipLeft)
                {
                    pos.X -= textSize.X;
                }
                TOOL_TIP_PANEL.Draw(gameTime, spriteBatch, pos, textSize, 0.0000001f);
                spriteBatch.DrawString(font, toolTipText, pos, ForeColor,
                    0, Vector2.Zero, 1, SpriteEffects.None, 0);
            }
            
        }
        public void SetRandomColor()
        {
           //  = new Random(System.Environment.TickCount);
            Color = COLOR_SET[Constant.random.Next(COLOR_SET.Length)];
            foreColor = Color.Lerp(Color, Color.Black, 0.8f);
            //foreColor = Color;
        }
        public static Color GetAColor()
        {
            return COLOR_SET[Constant.random.Next(COLOR_SET.Length)];

        }
    }
}
